(function ($) {
    $.fn.yqResource = function (opts, param) {
        if (typeof opts == 'string') {
            return $.fn.yqResource.methods[opts](this, param);
        }

        return this.each(function () {
            var $this = $(this);
            var opt;
            if ($this.data("yqtype") == "yqResource") {
                var $uniqueID = $this.attr("ID");
                var opts_ = $.extend({}, options($this));
                destroy($this);
                $this = $("#" + $uniqueID);
                opt = $.extend(opts_, opts);
            } else {
                opt = $.extend({}, $.fn.yqResource.defaults, opts);
                var $uniqueID = $this.attr("ID");
                if ($uniqueID === undefined || $uniqueID === null || $uniqueID == "") {
                    $uniqueID = "yqResource";
                    $this.attr("ID", $uniqueID);
                }
            }

            if (opt.width === undefined && $this.width() > 0) {
                opt.width = $this.width();
            }
            else if (typeof opt.width != "undefined") {
                $this.width(opt.width);
            }

            if (opt.height === undefined && $this.height() > 0) {
                opt.height = $this.height();
            }
            else if (typeof opt.height != "undefined") {
                $this.height(opt.height);
            }

            //组件加载结束
            opt.onload = true;
            //组件进程执行中
            opt.running = false;

            //变量信息
            $this.data("resource_opt", opt);
            $this.data("yqtype", "yqResource");

            opt.baseid = $this.attr("ID");

            var file = [];
            file.push({ url: "/scripts/crypto/sha256.min.js", type: "js" });
            $.yqLoadJsCss(file, function () {
                init_layout($this);
            })

            return $this;
        });
    };

    $.fn.yqResource.defaults = {
        readmeurl: "https://www.yqsite.com",
        theme: "eclipse",
        fontSize: 14,
    };

    $.fn.yqResource.methods = {
        options: function (jq) {
            return options($(jq));
        },
        resize: function (jq, params) {
            resize($(jq), params)
        }, destroy: function (jq) {
            destroy($(jq[0]));
        },
    };

    function options($object) {
        return $object.data("resource_opt");
    }

    function resize($object, params) {
        var opt = options($object);
        if (!(params === undefined)) {
            if (!(params.width === undefined)) {
                opt.width = params.width;
            }
            if (!(params.height === undefined)) {
                opt.height = params.height;
            }
        }

        if (opt.west_collapse === undefined) {
            opt.$lo.layout("resize", {
                width: opt.width,
                height: opt.height
            });
        }

        var $center = opt.$lo.layout("panel", "center");
        opt.$m_tabs.tabs("resize", {
            width: $center.width(),
            height: $center.height()
        });


        var tabs = opt.$m_tabs.tabs("tabs");
        var s_opt = opt.$m_tabs.tabs("getSelected").panel("options");

        for (let i = 0; i < tabs.length; i++) {
            var p_opt = $(tabs[i]).panel("options");
            if (p_opt.show_type == "file") {
                p_opt.show_edit.yqFileEdit("resize",
                    {
                        height: opt.$m_tabs.height() - 34,
                        width: s_opt.$body.width()
                    });
            } else if (p_opt.show_type == "ujson") {
                p_opt.show_edit.yqUJsonEdit("resize",
                    {
                        height: opt.$m_tabs.height() - 34,
                        width: s_opt.$body.width()
                    });
            } else if (p_opt.show_type == "htmls") {
                p_opt.show_edit.yqHtmlFileEdit("resize",
                    {
                        height: opt.$m_tabs.height() - 34,
                        width: s_opt.$body.width()
                    });
            } else if (p_opt.show_type == "image") {
                p_opt.$img.css({ width: s_opt.$body.width() });
            }
        }

        if (!(opt.setResizeTime === undefined)) {
            clearInterval(opt.setResizeTime);
            opt.setResizeTime = undefined;
        };

        delete opt.west_collapse;
    }

    function destroy($object) {
        var opt = options($object);

        var tabs = opt.$m_tabs.tabs("tabs");
        for (let i = 0; i < tabs.length; i++) {
            var p_opt = $(tabs[i]).panel("options");
            if (p_opt.show_type == "file") {
                //p_opt.$title.find(".edit").switchbutton("destroy");
                //p_opt.$title.find(".save").linkbutton("destroy");
                //p_opt.$title.find(".reload").linkbutton("destroy");
                //p_opt.$title.find(".download").linkbutton("destroy");
                p_opt.show_edit.yqFileEdit("destroy");
            } else if (p_opt.show_type == "ujson") {
                p_opt.show_edit.yqUJsonEdit("destroy");
            } else if (p_opt.show_type == "htmls") {
                p_opt.show_edit.yqHtmlFileEdit("destroy");
            } else if (p_opt.show_type == "image") {
                p_opt.$img.css({ width: p_opt.$body.width() });
            }
        }

        for (let i = tabs.length - 1; i >= 0; i--) {
            opt.$m_tabs.tabs("close", i);
        }

        //opt.$m_tabs.tabs("destroy");
        //opt.$tree.tree("destroy");
        //opt.$lo.layout("destroy");
        opt.$menu.menu("destroy");
        $object.empty();
        $object.removeClass("easyui-layout");
        $object.removeClass("layout");
        if ($object.attr("class") == "") {
            $object.removeAttr("class")
        }
    }

    function init_layout($object) {
        var opt = options($object);
        //var $uniqueID = $object.attr("id");

        opt.$lo = $object.layout({
            width: opt.width,
            height: opt.height
        });

        var $menu = $('<div style="width:120px;">');
        $menu.menu({
            onclick: function (item) {

            }
        });

        //$menu.menu('appendItem', {
        //    id: "tv_moreedit",
        //    text: '更多...',
        //    //onclick: function(){alert('New Item')}
        //});

        //var item = $menu.menu('findItem', { id: 'tv_moreedit' });  // find 'Open' item

        $menu.menu('appendItem', {
            //parent: item.target,
            id: "docConvert_pdf",
            text: 'docx=>pdf',
            //iconCls: 'icon-excel',
            onclick: function () {
                file_docConvert("pdf");
            }
        });

        $menu.menu('appendItem', {
            //parent: item.target,
            id: "docConvert_imge",
            text: 'docx=>jpg',
            //iconCls: 'icon-excel',
            onclick: function () {
                file_docConvert("imge");
            }
        });

        opt.$lo_menu = $menu;

        opt.$lo.layout("add", {
            region: 'west',
            title: '文件树',
            tools: [{
                iconCls: 'yqwin-btn-icon fa fa-angle-double-down more_tools_menu',
                handler: function () {

                }
            }],
            width: 250,
            split: true
        });

        var $tools = opt.$lo.find(".more_tools_menu");
        console.log("$tools", $tools);
        $tools.mouseover(function () {
            var $panel = opt.$lo.layout("panel", "west");
            //console.log($panel);
            opt.$lo_menu.menu('show', {
                left: $panel.panel('options').left + $panel.panel('header').width() - 25,
                top: $panel.panel('options').top + 25
            });
        });



        opt.$lo.layout("add", {
            region: 'center'
        });

        var $west = opt.$lo.layout("panel", "west");
        opt.$tree = $("<ul></ul>");
        $west.append(opt.$tree);

        opt.edit_index = 0;
        opt.cut_node = null;
        opt.copy_node = null;

        var $center = opt.$lo.layout("panel", "center");
        opt.$m_tabs = $("<div></div>");
        opt.$m_tabs.css({
            width: $center.width(),
            height: $center.height()
        });
        $center.append(opt.$m_tabs);
        opt.$m_tabs.tabs({
            border: false,
            onSelect: function (title) {
                //alert(title + ' is selected');
            },
            onBeforeClose: function (title, index) {
                //console.log("onBeforeClose:function(title,index)", title);
                var tab = opt.$m_tabs.tabs("getTab", index);
                var tab_opt = tab.panel("options");
                if (tab_opt.show_type == "file") {
                    tab_opt.show_edit.yqFileEdit("destroy");
                } else if (tab_opt.show_type == "ujson") {
                    tab_opt.show_edit.yqUJsonEdit("destroy");
                } else if (tab_opt.show_type == "htmls") {
                    tab_opt.show_edit.yqHtmlFileEdit("destroy");
                }
            },
            onContextMenu: function (e, title, index) {
                console.log("onContextMenu", e, title, index);
                var tabs = opt.$m_tabs.tabs("tabs");
                if (tabs.length == 1) {
                    return;
                }
                var i_close = opt.$tabs_menu.menu('findItem', { name: 'close' });
                var i_closeall = opt.$tabs_menu.menu('findItem', { name: 'closeall' });
                var i_other = opt.$tabs_menu.menu('findItem', { name: 'other' });
                var i_left = opt.$tabs_menu.menu('findItem', { name: 'left' });
                var i_right = opt.$tabs_menu.menu('findItem', { name: 'right' });
                if (index == 0) {
                    opt.$tabs_menu.menu('disableItem', i_close.target);
                } else {
                    opt.$tabs_menu.menu('enableItem', i_close.target);
                }
                if (index > 1) {
                    opt.$tabs_menu.menu('enableItem', i_left.target);
                } else {
                    opt.$tabs_menu.menu('disableItem', i_left.target);
                }
                if (index == 1 && tabs.length == 2) {
                    opt.$tabs_menu.menu('disableItem', i_closeall.target);
                    opt.$tabs_menu.menu('disableItem', i_other.target);
                } else {
                    opt.$tabs_menu.menu('enableItem', i_closeall.target);
                    opt.$tabs_menu.menu('enableItem', i_other.target);
                }
                if (index < (tabs.length - 1)) {
                    opt.$tabs_menu.menu('enableItem', i_right.target);
                } else {
                    opt.$tabs_menu.menu('disableItem', i_right.target);
                }

                e.preventDefault();
                opt.tree_e = e;
                opt.$tabs_index = {
                    count: tabs.length,
                    index: index
                };
                opt.$tabs_menu.menu('show', {
                    left: e.pageX,
                    top: e.pageY
                });
            }
        });

        opt.$tabs_menu = $(`<div style="width:120px;">
        <div data-options="name:'close',iconCls:'icon2-close'">关闭</div>
        <div data-options="name:'closeall',iconCls:'icon2-closeall'">全部关闭</div>
        <div class="menu-sep"></div>
        <div data-options="name:'other',iconCls:'icon2-closeother'">关闭其他</div>
        <div data-options="name:'left',iconCls:'icon2-closeleft'">关闭左侧</div>
        <div data-options="name:'right',iconCls:'icon2-closeright'">关闭右侧</div>
    </div>`);

        opt.$tabs_menu.menu({
            onClick: function (item) {
                if (item.name == "close") {
                    opt.$m_tabs.tabs("close", opt.$tabs_index.index);
                } else if (item.name == "closeall") {
                    for (let j = (opt.$tabs_index.count - 1); j > 0; j--) {
                        opt.$m_tabs.tabs("close", j);
                    }
                } else if (item.name == "other") {
                    for (let j = (opt.$tabs_index.count - 1); j > 0; j--) {
                        if (j != opt.$tabs_index.index) {
                            opt.$m_tabs.tabs("close", j);
                        }
                    }
                } else if (item.name == "left") {
                    for (let j = (opt.$tabs_index.index - 1); j > 0; j--) {
                        opt.$m_tabs.tabs("close", j);
                    }
                } else if (item.name == "right") {
                    for (let j = (opt.$tabs_index.count - 1); j > opt.$tabs_index.index; j--) {
                        opt.$m_tabs.tabs("close", j);
                    }
                }
            }
        });

        // add a new tab panel
        opt.$m_tabs.tabs('add', {
            title: 'readme',
            onOpen: function () {
                var p_opt = $(this).panel("options");
                if (!(p_opt.id_ === undefined)) {
                    return;
                }

                p_opt.id_ = "readme.md";
                var $body = $(this).panel("body");
                p_opt.$body = $body;
                fileinfo(p_opt.id_, function (res) {
                    if (res.error != 0) {
                        yqMessager("error", res.info + "[" + res.error + "]");
                        return;
                    }

                    p_opt.show_type = "file";

                    var $div = $('<textarea style="width:100%;height:100%;"></textarea>');
                    $div.attr("id", $.getUniqueID());
                    $body.append($div);
                    $div.css({ height: opt.$m_tabs.height() - 34, width: $body.width() });
                    p_opt.show_edit = $div;
                    $div.yqFileEdit({
                        theme: opt.theme,
                        fontSize: opt.fontSize,
                        data: res.data,
                        width: $body.width(),
                        height: opt.$m_tabs.height() - 34,
                        runfile: true,
                        afterBindingTitle: function () {

                        }, //标题绑定后
                    });
                });
            },
            closable: false,
        });

        opt.$tree.tree({
            onContextMenu: function (e, node) {
                $(this).tree('select', node.target);
                treeContextMenu($object, e, node);
            },
            onDblClick: function (node) {
                if (node.attributes.type == "file") {
                    fileview($object, node);
                }
            },
            onClick: function (node) {
                //console.log(node);
            }
        });

        var $menu = $('<div style="width:120px;">');
        opt.$menu = $menu;
        $menu.menu({
            onclick: function (item) {

            }
        });

        $menu.menu('appendItem', {
            id: "tv_addfile",
            text: '新建文件',
            iconCls: 'yqwin-btn-icon-sub fa fa-file-code-o',
            onclick: function () {
                fileAdd($object, opt.conMenuNode);
            }
        });

        $menu.menu('appendItem', {
            id: "tv_addpath",
            text: '新建文件夹',
            iconCls: 'yqwin-btn-icon-sub fa fa-folder-o',
            onclick: function () {
                pathAdd($object, opt.conMenuNode);
            }
        });

        $menu.menu('appendItem', {
            id: "tv_rename",
            text: '重命名',
            iconCls: 'yqwin-btn-icon-sub fa fa-terminal',
            onclick: function () {
                if (opt.conMenuNode.attributes.type == "file") {
                    fileRename($object, opt.conMenuNode);
                } else {
                    pathRename($object, opt.conMenuNode);
                }
            }
        });

        $menu.menu('appendItem', {
            id: "tv_remove",
            text: '删除',
            iconCls: 'yqwin-btn-icon-sub fa fa-trash',
            onclick: function () {
                if (opt.conMenuNode === null) {
                    return;
                }
                if (opt.conMenuNode.attributes.type == "file") {
                    fileDel($object, opt.conMenuNode);
                } else {
                    pathDel($object, opt.conMenuNode);
                }
            }
        });

        $menu.menu('appendItem', {
            separator: true
        });

        $menu.menu('appendItem', {
            id: "tv_cut",
            text: '剪切',
            iconCls: 'yqwin-btn-icon-sub fa fa-scissors',
            onclick: function () {
                var node = null;
                if (!(opt.cut_node === null)) {
                    node = opt.cut_node;
                } else if (!(opt.copy_node === null)) {
                    node = opt.copy_node;
                }
                if (!(node === null)) {
                    opt.$tree.tree("update", {
                        "target": node.target,
                        "text": node.attributes._text
                    });
                }

                opt.cut_node = opt.conMenuNode;
                opt.copy_node = null;

                console.log(opt.conMenuNode.attributes);
                opt.$tree.tree("update", {
                    "target": opt.conMenuNode.target,
                    "text": '<i style="color:#DC143C;">' + opt.conMenuNode.attributes._text + '<i/>'
                });
            }
        });

        $menu.menu('appendItem', {
            id: "tv_copy",
            text: '复制',
            iconCls: 'yqwin-btn-icon-sub fa fa-files-o',
            onclick: function () {
                var node = null;
                if (!(opt.cut_node === null)) {
                    node = opt.cut_node;
                } else if (!(opt.copy_node === null)) {
                    node = opt.copy_node;
                }
                if (node != null) {
                    opt.$tree.tree("update", {
                        "target": node.target,
                        "text": node.attributes._text
                    });
                }

                opt.cut_node = null;
                opt.copy_node = opt.conMenuNode;

                opt.$tree.tree("update", {
                    "target": opt.conMenuNode.target,
                    "text": '<i style="color:#00A36C;">' + opt.conMenuNode.attributes._text + '<i/>'
                });
            }
        });

        $menu.menu('appendItem', {
            id: "tv_unc_c",
            text: '清除',
            iconCls: 'yqwin-btn-icon-sub fa fa-chain-broken',
            onclick: function () {
                var node = null;
                if (!(opt.cut_node === null)) {
                    node = opt.cut_node;
                } else if (!(opt.copy_node === null)) {
                    node = opt.copy_node;
                }

                if (node != null) {
                    opt.$tree.tree("update", {
                        "target": node.target,
                        "text": node.attributes._text
                    });
                }

                opt.cut_node = null;
                opt.copy_node = null;
            }
        });

        $menu.menu('appendItem', {
            id: "tv_paste",
            text: '粘贴',
            iconCls: 'yqwin-btn-icon-sub fa fa-clipboard',
            onclick: function () {
                if (!(opt.cut_node === null)) { //剪切  文件夹或文件
                    if (opt.cut_node.attributes.type == "file") {
                        filePaste($object);
                    } else {
                        pathPaste($object);
                    }
                } else if (!(opt.copy_node === null)) { //拷贝 文件
                    if (opt.copy_node.attributes.type == "file") {
                        fileCopy($object);
                    }
                }
            }
        });

        $menu.menu('appendItem', {
            separator: true
        });

        $menu.menu('appendItem', {
            id: "icon2-rs-reload",
            text: '刷新',
            iconCls: 'yqwin-btn-icon-sub fa fa-repeat',
            onclick: function () {
                reload($object, opt.conMenuNode);
            }
        });

        $menu.menu('appendItem', {
            id: "tv_view",
            text: '查看文件',
            iconCls: 'yqwin-btn-icon-sub fa fa-eye',
            onclick: function () {
                fileview($object, opt.conMenuNode)
            }
        });

        $menu.menu('appendItem', {
            id: "tv_upload",
            text: '上传文件',
            iconCls: 'yqwin-btn-icon-sub fa fa-upload',
            onclick: function () {
                fileupload($object, opt.conMenuNode);
            }
        });

        $menu.menu('appendItem', {
            separator: true
        });

        $menu.menu('appendItem', {
            id: "tv_moreedit",
            text: '更多...',
            //onclick: function(){alert('New Item')}
        });

        var item = $menu.menu('findItem', { id: 'tv_moreedit' });  // find 'Open' item
        //console.log("item", item);

        $menu.menu('appendItem', {
            parent: item.target,
            id: "tv_copyurl",
            text: '复制路径',
            iconCls: 'yqwin-btn-icon-sub fa fa-link',
            onclick: function () {
                const el = document.createElement('input')
                el.setAttribute('value', opt.conMenuNode.id)
                document.body.appendChild(el)
                el.select()
                document.execCommand('copy')
                document.body.removeChild(el)
                $.yqMessager("success", "复制路径[" + opt.conMenuNode.id + "]成功");
            }
        });

        $menu.menu('appendItem', {
            parent: item.target,
            id: "tv_js_min",
            text: 'js=>min',
            //iconCls: 'icon-excel',
            onclick: function () {
                file_js_min($object, opt.conMenuNode);
            }
        });

        $menu.menu('appendItem', {
            parent: item.target,
            id: "tv_css_min",
            text: 'css=>min',
            //iconCls: 'icon-excel',
            onclick: function () {
                file_css_min($object, opt.conMenuNode);
            }
        });

        $menu.menu('appendItem', {
            parent: item.target,
            id: "tv_to_min",
            text: '=>min',
            //iconCls: 'icon-excel',
            onclick: function () {
                file_to_min($object, opt.conMenuNode);
            }
        });

        $menu.menu('appendItem', {
            parent: item.target,
            separator: true
        });

        $menu.menu('appendItem', {
            parent: item.target,
            id: "tv_download",
            text: '下载',
            //iconCls: 'icon-excel',
            onclick: function () {
                file_download($object, opt.conMenuNode);
            }
        });

        opt.$lo.layout("panel", "west").bind('contextmenu', function (e) {
            treeContextMenu($object, e, null);
        });

        loadData($object);

        //var $west = opt.$lo.layout("panel", "west");
        $west.panel("options").onResize = function (width, height) {
            if (opt.setResizeTime === undefined) {
                opt.setResizeTime = setTimeout(function () {
                    resize($object);
                }, 100);
            }
        }

        $west.panel("options").onCollapse = function () {
            opt.west_collapse = true;
            resize($object);
        }
    }

    function loadData($object) {
        var opt = options($object);
        yqRsRootPath(function (res) {
            if (res.error == 0) {
                if (res.data.length > 0) {
                    var nodes = convTrees(res.data[0]);
                    opt.$tree.tree("loadData", nodes);
                    getSubNode($object, opt.$tree.tree("getRoots"));
                }
            }
        });
    }

    function reload($object, node) {
        var opt = options($object);

        if (node === null) {
            loadData($object);
            return;
        }
        opt.cut_node = null;
        opt.copy_node = null;

        if (node.attributes.type == "path") {
            var children = opt.$tree.tree('getChildren', node.target);
            for (let i = 0; i < children.length; i++) {
                opt.$tree.tree('remove', children[i].target);
            }
            opt.$tree.tree('update', {
                target: node.target,
                state: "closed",
                attributes: {
                    type: "path",
                    open: false,
                    _text: node.attributes._text
                }
            });

            opt.$tree.tree('collapse', node.target);
            var nodes = [node];
            getSubNode($object, nodes, true)
        }
    }

    function getSubNode($object, nodes, open) {
        if (open === undefined) {
            open = false;
        }

        var opt = options($object);
        var paths = [];
        for (let i = 0; i < nodes.length; i++) {
            var node = nodes[i];
            if (node.attributes.type == "path") {
                if (node.attributes.open) {
                    return;
                }

                if (node.attributes.open == false) {
                    paths.push(node.id);
                }
            }
        }

        if (paths.length == 0) {
            return;
        }

        opt.$tree.tree("options").onExpand = function (node) {
            //console.log(node);
        };

        yqRsSubPath(paths, function (res) {
            if (res.error == 0) {
                for (let i = 0; i < res.data.length; i++) {
                    var subnodes = convTrees(res.data[i]);
                    for (let j = 0; j < nodes.length; j++) {
                        var node = nodes[j];
                        if (node.attributes.type == "path" &&
                            node.id == res.data[i].name) {
                            if (subnodes.length > 0) {
                                opt.$tree.tree('append', {
                                    parent: node.target,
                                    data: subnodes
                                });

                                var attributes = node.attributes;
                                attributes.open = true;
                                opt.$tree.tree('update', {
                                    target: node.target,
                                    state: "closed",
                                    attributes: attributes
                                });

                                opt.$tree.tree('toggle', node.target);
                                opt.$tree.tree('collapse', node.target);
                            } else {
                                var attributes = node.attributes;
                                attributes.open = true;
                                opt.$tree.tree('update', {
                                    target: node.target,
                                    state: "closed",
                                    attributes: attributes
                                });
                            }
                            break;
                        }
                    }
                }
            }

            opt.$tree.tree("options").onExpand = function (node) {
                var subnodes = opt.$tree.tree("getChildren", node.target);
                getSubNode($object, subnodes);
            };
        });
    }

    function treeContextMenu($object, e, node) {
        var opt = options($object);

        if (node === null) {
            opt.$menu.menu('enableItem', $('#tv_addfile')[0]);
            opt.$menu.menu('enableItem', $('#tv_addpath')[0]);
            opt.$menu.menu('disableItem', $('#tv_rename')[0]);
            opt.$menu.menu('disableItem', $('#tv_remove')[0]);

            opt.$menu.menu('disableItem', $('#tv_cut')[0]);
            opt.$menu.menu('disableItem', $('#tv_copy')[0]);

            opt.$menu.menu('enableItem', $('#tv_reload')[0]);
            opt.$menu.menu('disableItem', $('#tv_view')[0]);
            opt.$menu.menu('enableItem', $('#tv_upload')[0]);
            opt.$menu.menu('disableItem', $('#tv_copyurl')[0]);
            opt.$menu.menu('disableItem', $('#tv_js_min')[0]);
            opt.$menu.menu('disableItem', $('#tv_css_min')[0]);
            opt.$menu.menu('disableItem', $('#tv_to_min')[0]);
            opt.$menu.menu('disableItem', $('#tv_download')[0]);
        } else {
            opt.$menu.menu('enableItem', $('#tv_rename')[0]);
            opt.$menu.menu('enableItem', $('#tv_cut')[0]);
            opt.$menu.menu('enableItem', $('#tv_remove')[0]);

            opt.$menu.menu('enableItem', $('#tv_addfile')[0]);
            opt.$menu.menu('enableItem', $('#tv_addpath')[0]);
            if (node.attributes.type == 'file') {
                opt.$menu.menu('enableItem', $('#tv_copy')[0]);

                opt.$menu.menu('disableItem', $('#tv_reload')[0]);
                opt.$menu.menu('enableItem', $('#tv_view')[0]);
                opt.$menu.menu('disableItem', $('#tv_upload')[0]);

                //console.log("node.attributes", node.attributes);
                if (endsWith(node.attributes.name, '.min')) {
                    opt.$menu.menu('enableItem', $('#tv_js_min')[0]);
                    opt.$menu.menu('enableItem', $('#tv_css_min')[0]);
                } else {
                    opt.$menu.menu('disableItem', $('#tv_js_min')[0]);
                    opt.$menu.menu('disableItem', $('#tv_css_min')[0]);
                }
                if (endsWith(node.attributes.name, '.js') ||
                    endsWith(node.attributes.name, '.css')) {
                    if (node.attributes.name.indexOf('.min.') == -1) {
                        opt.$menu.menu('enableItem', $('#tv_to_min')[0]);
                    } else {
                        opt.$menu.menu('disableItem', $('#tv_to_min')[0]);
                    }
                } else {
                    opt.$menu.menu('disableItem', $('#tv_to_min')[0]);
                }
                opt.$menu.menu('enableItem', $('#tv_download')[0]);
            } else {
                opt.$menu.menu('disableItem', $('#tv_copy')[0]);

                opt.$menu.menu('enableItem', $('#tv_reload')[0]);
                opt.$menu.menu('disableItem', $('#tv_view')[0]);
                opt.$menu.menu('enableItem', $('#tv_upload')[0]);

                opt.$menu.menu('disableItem', $('#tv_js_min')[0]);
                opt.$menu.menu('disableItem', $('#tv_css_min')[0]);
                opt.$menu.menu('disableItem', $('#tv_to_min')[0]);
                opt.$menu.menu('disableItem', $('#tv_download')[0]);
            }
            opt.$menu.menu('enableItem', $('#tv_copyurl')[0]);
        }

        // f_node  文件夹  t_node 选择的文件夹
        var t_enable = false;
        if (!(opt.cut_node === null)) {
            opt.$menu.menu('enableItem', $('#tv_unc_c')[0]);
            if (opt.cut_node.attributes.type == "path") {
                t_enable = pathPasteEnable($object, opt.cut_node, node)
            } else {
                t_enable = filePasteEnable($object, opt.cut_node, node)
            }
        } else if (!(opt.copy_node === null)) {
            opt.$menu.menu('enableItem', $('#tv_unc_c')[0]);
            if (opt.copy_node.attributes.type == "path") {
                t_enable = false;
            } else {
                t_enable = fileCopyEnable($object, opt.copy_node, node)
            }
        } else {
            opt.$menu.menu('disableItem', $('#tv_unc_c')[0]);
            opt.$menu.menu('disableItem', $('#tv_paste')[0]);
        }

        if (t_enable) {
            opt.$menu.menu('enableItem', $('#tv_paste')[0]);
        } else {
            opt.$menu.menu('disableItem', $('#tv_paste')[0]);
        }

        opt.conMenuNode = node;
        e.preventDefault();
        opt.tree_e = e;
        opt.$menu.menu('show', {
            left: e.pageX,
            top: e.pageY
        });
    }

    function endsWith(str, suffix) {
        return str.indexOf(suffix, str.length - suffix.length) !== -1;
    }

    function pathAdd($object, node) {
        var opt = options($object);

        if (!(node === null)) {
            if (node.attributes.type == "file") {
                node = opt.$tree.tree("getParent", node.target);
                opt.conMenuNode = node;
            }
        }

        pathDialog($object, "添加文件夹", "", node === null ? false : true, function (p_res) {
            var filename = p_res.name;

            if (!(p_res.root)) {
                if (!(node === null)) {
                    filename = node.id + "/" + filename;
                }
            } else {
                node = null;
            }

            var formData = new FormData();
            formData.append("action", "newpath");
            formData.append("name", filename);

            $.ajax({
                type: 'POST',
                url: "_resource.html",
                data: formData,
                processData: false,
                contentType: false,
                dataType: "json",
                success: function (res) {
                    if (!$.yqDataErrCheck(res)) {
                        return;
                    }

                    if (res.error == 0) {
                        var f_node = {
                            id: filename,
                            text: p_res.name,
                            iconCls: "icon2-rs-folder",
                            state: "open",
                            attributes: {
                                type: "path",
                                _text: p_res.name,
                                open: true
                            }
                        };

                        if (node === null) {
                            opt.$tree.tree('append', {
                                data: f_node
                            });
                        } else {
                            opt.$tree.tree('append', {
                                parent: node.target,
                                data: f_node
                            });
                        }

                        $.messager.show({
                            title: 'success',
                            msg: '文件创建成功。',
                            timeout: 3000,
                            showType: 'show'
                        });
                    } else {
                        $.messager.alert('fail', '文件创建失败!' + res.info, 'info');
                    }
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    console.log(XMLHttpRequest.responseText);
                    $.messager.alert('fail', '文件创建失败!', 'info');
                }
            });
        })
    }

    function pathRename($object, node) {
        var opt = options($object);

        pathDialog($object, "修改文件夹名", node.attributes._text, false, function (p_res) {
            var p_node = opt.$tree.tree("getParent", node.target);
            var filename = p_res.name;
            if (!(p_node === null)) {
                filename = p_node.id + "/" + filename;
            }

            var formData = new FormData();
            formData.append("action", "renamepath");
            formData.append("f_path", node.id);
            formData.append("t_path", filename);

            if (node.id == filename) {
                $.messager.alert('fail', '文件夹名称未修改。', 'info');
                return;
            }

            $.ajax({
                type: 'POST',
                url: "_resource.html",
                data: formData,
                processData: false,
                contentType: false,
                dataType: "json",
                success: function (res) {
                    if (!$.yqDataErrCheck(res)) {
                        return;
                    }

                    if (res.error == 0) {
                        var attributes = node.attributes;
                        attributes._text = p_res.name;
                        opt.$tree.tree("update", {
                            target: node.target,
                            id: filename,
                            text: p_res.name,
                            attributes: attributes
                        });

                        var new_node = opt.$tree.tree("find", filename);
                        reload($object, new_node);

                        $.messager.show({
                            title: 'success',
                            msg: '文件夹重命名成功。',
                            timeout: 3000,
                            modtime: "2023-02-10 07:43:24",
                            showType: 'show'
                        });
                    } else {
                        $.messager.alert('fail', '文件夹重命名失败。' + res.info, 'info');
                    }
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    console.log(XMLHttpRequest.responseText);
                    $.messager.alert('fail', '文件夹重命名失败。', 'info');
                }
            });
        })
    }

    function pathDialog($object, title, name, is_add, callback) {
        var opt = options($object);
        var dgid = opt.baseid + "_dg";
        if ($("#" + dgid).length == 0) {
            $("body").append('<div id="' + dgid + '"></div>');
        }

        var dg_opt = {
            title: title,
            width: 300,
            height: is_add ? 190 : 170,
            closed: false,
            cache: false,
            modal: true,
            buttons: [{
                text: '确定',
                iconCls: 'icon-ok',
                handler: function () {
                    var $body = $("#" + dgid).dialog("body");
                    var v_name = $body.find(".name").textbox("getValue");
                    var v_root;
                    if (is_add) {
                        v_root = $body.find(".root").next().hasClass("checkbox-checked");
                    }


                    if (v_name == "") {
                        return;
                    }
                    var filename = v_name;
                    if (is_add) {
                        callback({ name: filename, root: v_root });
                    } else {
                        callback({ name: filename });
                    }

                    $("#" + dgid).dialog("close");
                }
            }, {
                text: '取消',
                iconCls: 'icon-no',
                handler: function () {
                    $("#" + dgid).dialog("close");
                }
            }],
            onOpen: function () {
                var $body = $("#" + dgid).dialog("body");
                var $inner;
                if (is_add) {
                    $inner = $(`
                    <table style="padding: 20px 0 0 20px;">
                      <tr>
                        <td>文件夹</td>
                        <td><input class="name" type="text" style="width:150px"></td>
                        <td></td>
                      </tr>
                      <tr>
                        <td>根目录</td>
                        <td><input class="root" type="checkbox" value="" /></td>
                      </tr>
                    </table>
                `);

                } else {
                    $inner = $(`
                    <table style="padding: 20px 0 0 20px;">
                      <tr>
                        <td>文件夹</td>
                        <td><input class="name" type="text" style="width:150px"></td>
                        <td></td>
                      </tr>
                    </table>
                `);
                }

                $body.append($inner);
                $inner.find(".name").textbox({});
                if (name === undefined || name === null || name == "") {
                    name = "";
                }
                $inner.find(".name").textbox("setValue", name);

                if (is_add) {
                    if (opt.conMenuNode === null) {
                        $inner.find(".root").checkbox({
                            checked: true,
                            disabled: true
                        });
                    } else {
                        $inner.find(".root").checkbox({
                            checked: false
                        });
                    }
                }
            },
            onClose: function () {
                $(this).dialog("destroy");
            }
        };

        opt.tree_e.clientY = opt.tree_e.clientY + 12;
        dg_opt = popPosition(dg_opt, opt.tree_e);
        $("#" + dgid).dialog(dg_opt);
    }

    function pathPaste($object) {
        var opt = options($object);
        var node = opt.cut_node;
        var path_node = opt.conMenuNode;

        var to_path = "";
        if (path_node === null) {
            to_path = node.attributes._text;
        }
        else {
            to_path = path_node.id + "/" + node.attributes._text;
        }

        var formData = new FormData();
        formData.append("action", "movepath");
        formData.append("f_path", node.id);
        formData.append("t_path", to_path);
        $.ajax({
            type: 'POST',
            url: "_resource.html",
            data: formData,
            processData: false,
            contentType: false,
            dataType: "json",
            success: function (res) {
                if (!$.yqDataErrCheck(res)) {
                    return;
                }

                if (res.error == 0) {
                    var pop_node = {
                        id: to_path,
                        text: node.attributes._text,
                        iconCls: node.iconCls,
                        children: [],
                        state: "closed",
                        attributes: $.extend({}, node.attributes)
                    };
                    pop_node.attributes._text = node.attributes._text;
                    opt.$tree.tree("remove", node.target);

                    if (path_node === null) {
                        opt.$tree.tree("append", {
                            data: pop_node
                        });
                    } else {
                        opt.$tree.tree("append", {
                            parent: path_node.target,
                            data: pop_node
                        });
                    }

                    var new_node = opt.$tree.tree("find", to_path);
                    reload($object, new_node);

                    opt.cut_node = null;
                    $.messager.show({
                        title: 'success',
                        msg: '文件移动成功。',
                        timeout: 3000,
                        showType: 'show'
                    });
                } else {
                    $.messager.alert('fail', '文件移动失败!' + res.info, 'info');
                }
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                console.log(XMLHttpRequest.responseText);
                $.messager.alert('fail', '文件移动失败!', 'info');
            }
        });
    }

    // f_node 剪切的文件夹  t_node 选择的文件夹
    function pathPasteEnable($object, f_node, t_node) {
        var opt = options($object);
        if (f_node === null) {
            return false;
        }

        var p_f_node = opt.$tree.tree("getParent", f_node.target);
        if (t_node === null) {
            if (p_f_node === null) {
                return false;
            } else {
                return true;
            }
        } else {
            if (t_node.attributes.type == "file") {
                return false;
            }

            if ((p_f_node === null && t_node === null) ||
                (!(p_f_node === null) && !(t_node === null) &&
                    p_f_node.id == t_node.id)
            ) {
                return false;
            } else {
                var enable = true;
                var $p_node = t_node
                while (!($p_node === null)) {
                    if (f_node.id == $p_node.id) {
                        enable = false;
                        break;
                    }
                    $p_node = opt.$tree.tree("getParent", $p_node.target);
                }
                return enable;

            }
        }
    }

    function pathDel($object, node) {
        var opt = options($object);
        $.messager.confirm({
            title: '删除文件夹',
            msg: '是否确定删除文件(' + node.text + ')?',
            fn: function (r) {
                if (r) {
                    var formData = new FormData();
                    formData.append("action", "delpath");
                    formData.append("name", node.id);
                    $.ajax({
                        type: 'POST',
                        url: "_resource.html",
                        data: formData,
                        processData: false,
                        contentType: false,
                        dataType: "json",
                        success: function (res) {
                            if (!$.yqDataErrCheck(res)) {
                                return;
                            }
                            //console.log(res);
                            if (res.error == 0) {
                                opt.$tree.tree("remove", node.target);
                                opt.cut_node = null;
                                opt.copy_node = null;
                                $.messager.show({
                                    title: 'success',
                                    msg: '文件夹删除成功。',
                                    timeout: 3000,
                                    showType: 'show'
                                });
                            } else {
                                $.messager.alert('fail', '文件夹删除失败!' + res.info, 'info');
                            }
                        },
                        error: function (XMLHttpRequest, textStatus, errorThrown) {
                            console.log(XMLHttpRequest.responseText);
                            $.messager.alert('fail', '文件夹删除失败!' + MLHttpRequest.responseText, 'info');
                        }
                    });
                }
            }
        });
    }

    //添加
    function fileAdd($object, node) {
        var opt = options($object);

        if (!(node === null)) {
            if (node.attributes.type == "file") {
                node = opt.$tree.tree("getParent", node.target);
                opt.conMenuNode = node;
            }
        }

        fileDialog($object, "添加文件", "", (node === null ? false : true), function (f_res) {
            var filename = f_res.name;
            if (!(f_res.root)) {
                if (!(node === null)) {
                    filename = node.id + "/" + filename;
                }
            } else {
                node = null;
            }

            var f_type = getFileType(filename);

            if (f_type == "ujson") {
                var f_json = {
                    "ui_mask": {
                        "ui_type": 17,
                        "editType": 1,
                        "param": {
                            "titles": [{
                                "is_func": false,
                                "name": "code",
                                "ui_title": "Code",
                                "ui_type": 2,
                                "ui_width": 80,
                                "ui_visible": true,
                                "ui_readonly": false,
                                "ui_mask": {}
                            }, {
                                "is_func": false,
                                "name": "name",
                                "ui_title": "Name",
                                "ui_type": 2,
                                "ui_width": 80,
                                "ui_visible": true,
                                "ui_readonly": false,
                                "ui_mask": {}
                            }
                            ],
                            "model": []
                        }
                    },
                    "data": {
                        "code": "code test",
                        "name": "name test"
                    }
                };

                const blob = new Blob([$.jsonFormat(f_json)], { type: f_res.mine });
                // createObjectURL() 静态方法创建一个 DOMString，其中包含一个 URL，该 URL 表示参数中给定的对象。

                var fileFingerprint;
                var reader = new FileReader();
                reader.onload = function () {
                    fileFingerprint = HashBase64(reader.result, 'SHA256');
                    in_upload();
                }
                reader.readAsArrayBuffer(blob);

                function in_upload() {
                    var formData = new FormData();
                    formData.set('action', 'uploadfile');
                    formData.set('file', blob);
                    formData.set('name', filename);
                    formData.set('finger', fileFingerprint);
                    $.ajax({
                        type: 'post',
                        url: "_resource.html",
                        data: formData,
                        cache: false,
                        processData: false,
                        contentType: false,
                        dataType: 'json',
                        success: function (res) {
                            if (!$.yqDataErrCheck(res)) {
                                return;
                            }

                            if (res.error == 0) {
                                file_add_tv($object, node, res.data);
                                $.messager.show({
                                    title: 'success',
                                    msg: '文件创建成功。',
                                    timeout: 3000,
                                    showType: 'show'
                                });
                            } else {
                                $.messager.alert('fail', '文件创建失败!' + res.info, 'info');
                            }
                        },
                        error: function (XMLHttpRequest, textStatus, errorThrown) {
                            console.error(errorThrown);
                            $.messager.alert('fail', '文件创建失败!' + res.info, 'info');
                        }
                    });

                }
            } else {
                var formData = new FormData();
                formData.append("action", "newfile");
                formData.append("name", filename);
                formData.append("mine", f_res.mine);
                $.ajax({
                    type: 'POST',
                    url: "_resource.html",
                    data: formData,
                    processData: false,
                    contentType: false,
                    dataType: "json",
                    success: function (res) {
                        if (res.error == 0) {
                            file_add_tv($object, node, res.data);
                            $.messager.show({
                                title: 'success',
                                msg: '文件创建成功。',
                                timeout: 3000,
                                showType: 'show'
                            });
                        } else {
                            $.messager.alert('fail', '文件创建失败!' + res.info, 'info');
                        }
                    },
                    error: function (XMLHttpRequest, textStatus, errorThrown) {
                        console.log(XMLHttpRequest.responseText);
                        $.messager.alert('fail', '文件创建失败!', 'info');
                    }
                });
            }
        })
    }

    function fileRename($object, node) {
        var opt = options($object);

        fileDialog($object, "修改文件名", node.attributes._text, false, function (f_res) {
            var p_node = opt.$tree.tree("getParent", node.target);
            var filename = f_res.name;
            if (!(p_node === null)) {
                filename = p_node.id + "/" + filename;
            }

            if (node.id == filename) {
                $.messager.alert('fail', '文件名未修改。', 'info');
                return;
            }

            var formData = new FormData();
            formData.append("action", "renamefile");
            formData.append("f_name", node.id);
            formData.append("t_name", filename);

            $.ajax({
                type: 'POST',
                url: "_resource.html",
                data: formData,
                processData: false,
                contentType: false,
                dataType: "json",
                success: function (res) {
                    if (!$.yqDataErrCheck(res)) {
                        return;
                    }

                    if (res.error == 0) {
                        var attributes = node.attributes;
                        attributes._text = f_res.name;
                        opt.$tree.tree("update", {
                            target: node.target,
                            id: filename,
                            text: f_res.name,
                            attributes: attributes
                        });

                        $.messager.show({
                            title: 'success',
                            msg: '文件重命名成功。',
                            timeout: 3000,
                            showType: 'show'
                        });
                    } else {
                        $.messager.alert('fail', '文件重命名失败!' + res.info, 'info');
                    }
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    console.log(XMLHttpRequest.responseText);
                    $.messager.alert('fail', '文件重命名失败!', 'info');
                }
            });

        })
    }

    function fileDialog($object, title, name, is_add, callback) {
        var opt = options($object);
        var dgid = opt.baseid + "_dg";
        if ($("#" + dgid).length == 0) {
            $("body").append('<div id="' + dgid + '"></div>');
        }
        var dg_opt = {
            title: title,
            width: 355,
            height: is_add ? 180 : 160,
            closed: false,
            cache: false,
            modal: true,
            buttons: [{
                text: '确定',
                iconCls: 'icon-ok',
                handler: function () {
                    var $body = $("#" + dgid).dialog("body");
                    var v_name = $body.find(".name").textbox("getValue");
                    var v_type = $body.find(".type").combobox("getValue");
                    var v_root;
                    if (is_add) {
                        v_root = $body.find(".root").next().hasClass("checkbox-checked");
                    }
                    if (v_name == "") {
                        return;
                    }
                    var filename = v_name + "." + v_type;
                    var v_mine;
                    var data = $body.find(".type").combobox("getData");
                    for (let i = 0; i < data.length; i++) {
                        if (data[i].id == v_type) {
                            v_mine = data[i].mine;
                            break;
                        }
                    }
                    $("#" + dgid).dialog("close");
                    if (is_add) {
                        callback({ "name": filename, "mine": v_mine, root: v_root });
                    } else {
                        callback({ "name": filename, "mine": v_mine });
                    }
                }
            }, {
                text: '取消',
                iconCls: 'icon-no',
                handler: function () {
                    $("#" + dgid).dialog("close");
                }
            }],
            onOpen: function () {
                var $body = $("#" + dgid).dialog("body");

                var $inner;
                if (is_add) {
                    $inner = $(`
                    <table style="padding: 20px 0 0 20px;">
                      <tr>
                        <td>文件名</td>
                        <td><input class="name" type="text" style="width:150px"></td>
                        <td>.<input class="type" style="width:70px"></td>
                      </tr>
                      <tr>
                        <td>根目录</td>
                        <td colspan="2"><input class="root" type="checkbox" value="" /></td>
                      </tr>
                    </table>
                `);
                } else {
                    $inner = $(`
                    <table style="padding: 20px 0 0 20px;">
                      <tr>
                        <td>文件名</td>
                        <td><input class="name" type="text" style="width:150px"></td>
                        <td>.<input class="type" style="width:70px"></td>
                      </tr>
                    </table>
                `);
                }

                var n_ = "";
                var t_ = "";
                if (!(name === undefined || name === null || name == "")) {
                    if (name.lastIndexOf(".") > 0) {
                        n_ = name.substring(0, name.lastIndexOf("."));
                        t_ = name.substring(name.lastIndexOf(".") + 1);
                    } else {
                        n_ = name;
                    }
                }

                $body.append($inner);
                $inner.find(".name").textbox({});
                var data = [{
                    "id": "html",
                    "text": "html",
                    "mine": "text/html"
                }, {
                    "id": "aspx",
                    "text": "aspx",
                    "mine": "text/aspx"
                }, {
                    "id": "js",
                    "text": "js",
                    "mine": "text/plain",
                }, {
                    "id": "cs",
                    "text": "cs",
                    "mine": "text/plain",
                }, {
                    "id": "txt",
                    "text": "txt",
                    "mine": "text/plain",
                }, {
                    "id": "json",
                    "text": "json",
                    "mine": "text/json",
                }, {
                    "id": "xml",
                    "text": "xml",
                    "mine": "text/xml",
                }, {
                    "id": "min",
                    "text": "min",
                    "mine": "text/plain",
                }, {
                    "id": "md",
                    "text": "md",
                    "mine": "text/plain",
                }, {
                    "id": "htmls",
                    "text": "htmls",
                    "mine": "text/html",
                }, {
                    "id": "ujson",
                    "text": "ujson",
                    "mine": "text/json",
                }];

                if (t_ == "") {
                    t_ = "html";
                }

                var has_ = false;
                for (let i = 0; i < data.length; i++) {
                    const item = data[i];
                    if (item.id == t_) {
                        has_ = true;
                    }
                }

                if (!has_) {
                    data.push({
                        "id": t_,
                        "text": t_,
                        "mine": t_ + "/plain",
                    });
                }

                $inner.find(".type").combobox({
                    value: 1,
                    data: data,
                    valueField: "id",
                    textField: "text"
                });

                if (is_add) {
                    if (opt.conMenuNode === null) {
                        $inner.find(".root").checkbox({
                            checked: true,
                            disabled: true
                        });
                    } else {
                        $inner.find(".root").checkbox({
                            checked: false
                        });
                    }
                }

                $inner.find(".name").textbox("setValue", n_);
                if (t_ != "") {
                    $inner.find(".type").combobox("setValue", t_);
                }
            },
            onClose: function () {
                $(this).dialog("destroy");
            }
        };

        opt.tree_e.clientY = opt.tree_e.clientY + 12;
        dg_opt = popPosition(dg_opt, opt.tree_e);
        $("#" + dgid).dialog(dg_opt);
    }

    function fileCopy($object) {
        var opt = options($object);
        var node = opt.copy_node;
        var path_node = opt.conMenuNode;

        var p_node = opt.$tree.tree("getParent", node.target);
        var filepath = "";
        if (!(p_node === null)) {
            filepath = p_node.id;
        }

        var to_path = "";
        if (!(path_node === null)) {
            to_path = path_node.id;
        }

        var to_filename;
        if (filepath == to_path) {
            var c_nodes;
            if (path_node === null) {
                c_nodes = opt.$tree.tree("getRoots");
            } else {
                c_nodes = opt.$tree.tree("getChildren", path_node.target);
            }
            to_filename = node.id.substring(0, node.id.lastIndexOf(".")) + ' copy' + node.id.substring(node.id.lastIndexOf("."));
            var i = 0;
            var hasitem = true;
            while (hasitem) {
                var _to_filename = to_filename;
                for (let j = 0; j < c_nodes.length; j++) {
                    if (c_nodes[j].id == to_filename) {
                        i++;
                        to_filename = node.id.substring(0, node.id.lastIndexOf(".")) + ' copy' + i + node.id.substring(node.id.lastIndexOf("."));
                        break;
                    }
                }
                if (_to_filename == to_filename) {
                    hasitem = false;
                }
            }
        } else {
            if (to_path == "") {
                to_filename = node.attributes._text;
            } else {
                to_filename = to_path + "/" + node.attributes._text;
            }
        }

        //console.log(node.id, to_filename);
        var formData = new FormData();
        formData.append("action", "copyfile");
        formData.append("f_name", node.id);
        formData.append("t_name", to_filename);
        $.ajax({
            type: 'POST',
            url: "_resource.html",
            data: formData,
            processData: false,
            contentType: false,
            dataType: "json",
            success: function (res) {
                if (!$.yqDataErrCheck(res)) {
                    return;
                }

                if (res.error == 0) {
                    opt.$tree.tree("update", {
                        "target": node.target,
                        "text": node.attributes._text
                    });

                    opt.copy_node = null;

                    file_add_tv($object, path_node, res.data);

                    $.messager.show({
                        title: 'success',
                        msg: '文件拷贝成功。',
                        timeout: 3000,
                        showType: 'show'
                    });
                } else {
                    $.messager.alert('fail', '文件拷贝失败!' + res.info, 'info');
                }

            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                console.log(XMLHttpRequest.responseText);
                $.messager.alert('fail', '文件拷贝失败!', 'info');
            }

        });
    }

    function fileCopyEnable($object, file_node, path_node) {
        var opt = options($object);

        if (path_node === null) {
            return true;
        }

        if (path_node.attributes.type == "path") {
            return true;
        } else {
            return false;
        }
    }

    function filePaste($object) {
        var opt = options($object);
        var node = opt.cut_node;
        var path_node = opt.conMenuNode;

        var p_node = opt.$tree.tree("getParent", node.target);
        var filepath = "";
        if (!(p_node === null)) {
            filepath = p_node.id;
        }

        var to_path = "";
        if (!(path_node === null)) {
            to_path = path_node.id;
        }

        var to_filename;
        if (filepath == to_path) {
            $.messager.alert('fail', '文件已在该目录!', 'info');
            return;
        } else {
            if (to_path == "") {
                to_filename = node.attributes._text;
            } else {
                to_filename = to_path + "/" + node.attributes._text;
            }
        }

        var formData = new FormData();
        formData.append("action", "movefile");
        formData.append("f_name", node.id);
        formData.append("t_name", to_filename);
        $.ajax({
            type: 'POST',
            url: "_resource.html",
            data: formData,
            processData: false,
            contentType: false,
            dataType: "json",
            success: function (res) {
                if (!$.yqDataErrCheck(res)) {
                    return;
                }

                if (res.error == 0) {
                    opt.$tree.tree("remove", node.target);
                    opt.cut_node = null;
                    file_add_tv($object, path_node, res.data);

                    $.messager.show({
                        title: 'success',
                        msg: '文件移动成功。',
                        timeout: 3000,
                        showType: 'show'
                    });
                } else {
                    $.messager.alert('fail', '文件移动失败!' + res.info, 'info');
                }
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                console.log(XMLHttpRequest.responseText);
                $.messager.alert('fail', '文件移动失败!', 'info');
            }
        });
    }

    function filePasteEnable($object, file_node, path_node) {
        var opt = options($object);

        var p_file_node = opt.$tree.tree("getParent", file_node.target);

        if (path_node === null && p_file_node === null) {
            return false;
        } else {
            return true;
        }
    }

    //上传文件
    function fileupload($object, node) {
        var $input = $('<input type="file" multiple></input>')
        $input.bind("change", function () {
            var files = this.files;
            upload(files, 0);
        });

        $input.click();

        function upload(files, f_index) {
            if (files.length == f_index) {
                return;
            }

            var file = files[f_index];
            var fileFingerprint;
            var reader = new FileReader();
            reader.onload = function () {
                fileFingerprint = HashBase64(reader.result, 'SHA256');
                run_upload();
            }
            reader.readAsArrayBuffer(file);
            function run_upload() {
                var formData = new FormData();
                formData.set('action', 'uploadfile');
                formData.set('file', file);
                formData.set('name', node.id + "/" + file.name);
                formData.set('finger', fileFingerprint);
                $.ajax({
                    type: 'post',
                    url: "_resource.html",
                    data: formData,
                    cache: false,
                    processData: false,
                    contentType: false,
                    dataType: 'json',
                    success: function (res) {
                        if (!$.yqDataErrCheck(res)) {
                            return;
                        }

                        if (res.error == 0) {
                            file_add_tv($object, node, res.data);
                            upload(files, f_index + 1);
                        } else {
                            $.messager.alert('fail', '文件上传失败!' + res.info, 'info');
                        }
                    },
                    error: function (XMLHttpRequest, textStatus, errorThrown) {
                        console.error(errorThrown);
                        $.messager.alert('fail', '文件上传失败!' + errorThrown, 'info');
                    }
                });
            }
        }
    }

    //js 文件合并压缩
    function file_js_min($object, node) {
        var formData = new FormData();
        formData.set('action', 'js_min');
        formData.set('name', node.id);
        $.ajax({
            type: 'post',
            url: "_resource.html",
            data: formData,
            cache: false,
            processData: false,
            contentType: false,
            dataType: 'json',
            success: function (res) {
                if (!$.yqDataErrCheck(res)) {
                    return;
                }

                if (res.error == 0) {
                    $.messager.show({
                        title: 'success',
                        msg: 'js 文件合并成功，刷新目录查询。',
                        timeout: 3000,
                        showType: 'show'
                    });
                } else {
                    $.messager.alert('fail', 'js 文件合并压缩失败。' + res.info, 'info');
                }
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                console.error(errorThrown);
                $.messager.alert('fail', 'js 文件合并压缩失败。' + errorThrown + '', 'info');
            }
        });
    }

    function file_css_min($object, node) {
        var formData = new FormData();
        formData.set('action', 'css_min');
        formData.set('name', node.id);
        $.ajax({
            type: 'post',
            url: "_resource.html",
            data: formData,
            cache: false,
            processData: false,
            contentType: false,
            dataType: 'json',
            success: function (res) {
                if (!$.yqDataErrCheck(res)) {
                    return;
                }

                if (res.error == 0) {
                    $.messager.show({
                        title: 'success',
                        msg: 'css 文件合并成功，刷新目录查询。',
                        timeout: 3000,
                        showType: 'show'
                    });
                } else {
                    $.messager.alert('fail', 'css 文件合并压缩失败。' + res.info, 'info');
                }
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                console.error(errorThrown);
                $.messager.alert('fail', 'css 文件合并压缩失败。' + errorThrown + '', 'info');
            }
        });
    }

    function file_to_min($object, node) {
        var formData = new FormData();
        var type = "";
        var name = node.attributes.name;
        if (endsWith(name, '.js')) {
            type = "js";
        } else if (endsWith(name, '.css')) {
            type = "css";
        }
        if (type == "") {
            return;
        }

        formData.set('action', 'to_min');
        formData.set('name', node.id);

        $.ajax({
            type: 'post',
            url: "_resource.html",
            data: formData,
            cache: false,
            processData: false,
            contentType: false,
            dataType: 'json',
            success: function (res) {
                if (!$.yqDataErrCheck(res)) {
                    return;
                }

                if (res.error == 0) {
                    console.log(res);
                    $.messager.show({
                        title: 'success',
                        msg: type + '文件压缩成功，刷新目录查看。',
                        timeout: 3000,
                        showType: 'show'
                    });
                } else {
                    $.messager.alert('fail', type + '文件压缩失败。' + res.info, 'info');
                }
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                console.error(errorThrown);
                $.messager.alert('fail', type + '文件压缩失败。' + errorThrown + '', 'info');
            }
        });
    }

    function file_download($object, node) {
        var formData = new FormData();
        formData.set('action', 'download');
        formData.set('name', node.id);
        $.ajax({
            url: "_resource.html",
            type: 'POST',
            data: formData,
            processData: false,
            contentType: false,
            xhrFields: { responseType: 'blob' },
            success: function (data) {
                var blob = new Blob([data]);
                var url = window.URL.createObjectURL(blob);
                var link = document.createElement('a');
                link.href = url;
                link.download = node.text
                document.body.appendChild(link);
                link.click();

                window.URL.revokeObjectURL(url);
                document.body.removeChild(link);
            },
            error: function (xhr, status, error) {
                console.log(status, error);
            }
        });
    }

    function file_docConvert(type) {
        let $fileInput = $('<input type="file" accept=".docx"/>');
        $fileInput.on("change", function () {
            var fileInput = $fileInput[0];
            if (fileInput.files.length == 0) {
                $fileInput.remove();
                return;
            }

            var formData = new FormData();
            formData.append("action", "docconvert");
            formData.append("type", type);
            formData.append('wordinput', fileInput.files[0]);
            var _name = fileInput.files[0].name.replace(/\.[^.]+$/, '');
            //console.log(_name,fileInput.files[0]);

            $.ajax({
                url: "_resource.html",
                type: 'POST',
                data: formData,
                processData: false,
                contentType: false,
                xhrFields: { responseType: 'blob' },
                success: function (data) {
                    var blob = new Blob([data]);
                    var url = window.URL.createObjectURL(blob);
                    var link = document.createElement('a');
                    link.href = url;
                    if (type == "imge") {
                        link.download = _name + '.jpg';
                    } else {
                        link.download = _name + '.pdf';
                    }
                    document.body.appendChild(link);
                    link.click();

                    window.URL.revokeObjectURL(url);
                    document.body.removeChild(link);

                    $fileInput.remove();
                },
                error: function (xhr, status, error) {
                    console.log(status, error);
                    $fileInput.remove();
                }
            });
        });

        // 触发文件选择对话框  
        $fileInput.click();
    }

    function HashBase64(str, protocol = 'SHA256') {
        result = str
        switch (protocol) {
            case 'MD5':
                result = String.fromCharCode(...md5.array(str))
                break;
            case 'SHA1':
                result = String.fromCharCode(...sha1.array(str))
                break;
            case 'SHA224':
                result = String.fromCharCode(...sha224.array(str))
                break;
            case 'SHA256':
                result = String.fromCharCode(...sha256.array(str))
                break;
        }
        result = btoa(result).replaceAll("\/", "_").replaceAll("+", "-");
        return result;
    }

    function fileDel($object, node) {
        var opt = options($object);
        $.messager.confirm({
            title: '删除文件',
            msg: '是否确定删除文件(' + node.text + ')?',
            fn: function (r) {
                if (r) {
                    var formData = new FormData();
                    formData.append("action", "delfile");
                    formData.append("name", node.id);
                    $.ajax({
                        type: 'POST',
                        url: "_resource.html",
                        data: formData,
                        processData: false,
                        contentType: false,
                        dataType: "json",
                        success: function (res) {
                            if (!$.yqDataErrCheck(res)) {
                                return;
                            }

                            //console.log(res);
                            if (res.error == 0) {
                                opt.$tree.tree("remove", node.target);
                                opt.cut_node = null;
                                opt.copy_node = null;
                                $.messager.show({
                                    title: 'success',
                                    msg: '文件删除成功。',
                                    timeout: 3000,
                                    showType: 'show'
                                });
                            } else {
                                $.messager.alert('fail', '文件删除失败!' + res.info, 'info');
                            }
                        },
                        error: function (XMLHttpRequest, textStatus, errorThrown) {
                            console.log(XMLHttpRequest.responseText);
                            $.messager.alert('fail', '文件删除失败!' + MLHttpRequest.responseText, 'info');
                        }
                    });
                }
            }
        });
    }

    function file_add_tv($object, node, data) {
        var opt = options($object);

        var f_node = {
            id: node === null ? data.name : node.id + "/" + data.name,
            text: data.name,
            iconCls: "icon2-rs-file",
            state: "open",
            attributes: {
                type: "file",
                name: data.name,
                size: data.size,
                mine: data.mine,
                _text: data.name
            }
        };

        if (node === null) {
            opt.$tree.tree('append', {
                data: f_node
            });
        } else {
            opt.$tree.tree('append', {
                parent: node.target,
                data: f_node
            });
        }
    }

    //查看文件
    function fileview($object, node) {
        var opt = options($object);

        var tabs = opt.$m_tabs.tabs("tabs");
        for (let i = 0; i < tabs.length; i++) {
            const tab = tabs[i];
            if (tab.panel("options").id_ == node.id) {
                opt.$m_tabs.tabs("select", i);
                return;
            }
        }

        var filetype = getFileType(node.id);
        if (!(filetype == "html" ||
            filetype == "aspx" ||
            filetype == "js" ||
            filetype == "css" ||
            filetype == "json" ||
            filetype == "xml" ||
            filetype == "txt" ||
            filetype == "min" ||
            filetype == "md" ||
            filetype == "htmls" ||
            filetype == "ujson" ||
            node.attributes.mine.indexOf("image/") != -1 ||
            filetype == "config")) {
            return;
        }

        opt.$m_tabs.tabs('add', {
            title: node.text,
            closable: true,
            onOpen: function () {
                var p_opt = $(this).panel("options");
                if (!(p_opt.id_ === undefined)) {
                    return;
                }

                p_opt.id_ = node.id;
                p_opt.node = node;
                var $body = $(this).panel("body");
                $body.removeAttr("style");
                p_opt.$body = $body;

                if (filetype == "html" ||
                    filetype == "aspx" ||
                    filetype == "js" ||
                    filetype == "css" ||
                    filetype == "json" ||
                    filetype == "xml" ||
                    filetype == "txt" ||
                    filetype == "min" ||
                    filetype == "md" ||
                    filetype == "config") {

                    fileinfo(node.id, function (res) {
                        if (res.error != 0) {
                            yqMessager("error", res.info + "[" + res.error + "]");
                            return;
                        }

                        p_opt.show_type = "file";

                        var $div = $('<textarea style="width:100%;height:100%;"></textarea>');
                        $div.attr("id", $.getUniqueID());
                        $body.append($div);
                        $div.css({ height: opt.$m_tabs.height() - 34, width: $body.width() });

                        //console.log("res.data",res.data);

                        p_opt.show_edit = $div;
                        $div.yqFileEdit({
                            theme: opt.theme,
                            fontSize: opt.fontSize,
                            data: res.data,
                            width: $body.width(),
                            height: opt.$m_tabs.height() - 34,
                            runfile: true,
                            afterBindingTitle: function () {

                            }, //标题绑定后
                        });
                    });
                } else if (filetype == "ujson") {
                    fileinfo(node.id, function (res) {
                        if (res.error != 0) {
                            yqMessager("error", res.info + "[" + res.error + "]");
                            return;
                        }

                        p_opt.show_type = "ujson";

                        var $div = $('<div style="width:100%;height:100%;"></div>');
                        $div.attr("id", $.getUniqueID());
                        $body.append($div);
                        $div.css({ height: opt.$m_tabs.height() - 34, width: $body.width() });

                        p_opt.show_edit = $div;
                        $div.yqUJsonEdit({
                            theme: opt.theme,
                            fontSize: opt.fontSize,
                            data: res.data,
                            width: $body.width(),
                            height: opt.$m_tabs.height() - 34,
                            afterBindingTitle: function () {

                            }, //标题绑定后
                        });
                    });
                } else if (filetype == "htmls") {
                    //console.log(node);
                    fileinfo(node.id, function (res) {
                        if (res.error != 0) {
                            yqMessager("error", res.info + "[" + res.error + "]");
                            return;
                        }

                        p_opt.show_type = "htmls";

                        var $div = $('<textarea style="width:100%;height:100%;"></textarea>');
                        $div.attr("id", $.getUniqueID());
                        $body.append($div);
                        $div.css({ height: opt.$m_tabs.height() - 34, width: $body.width() });

                        p_opt.show_edit = $div;
                        $div.yqHtmlFileEdit({
                            data: res.data,
                            afterBindingTitle: function () {

                            }, //标题绑定后
                        });
                    });
                } else if (node.attributes.mine.indexOf("image/") != -1) {
                    p_opt.show_type = "image";

                    var $img = $(`<div><img></img></div>`);
                    p_opt.$img = $img;
                    $body.append($img);
                    $img.css({ overflow: "auto", height: opt.$m_tabs.height() - 34, width: $body.width() });
                    $img.find("img").attr("src", "_resource.html?action=downfile&file=" + encodeURIComponent(node.id))
                    //console.log(node);
                }
            }
        });
    }

    function getFileType(sFileTitle) {
        let pattern = /\.{1}[A-Za-z]{1,}$/;
        let fileType01 = sFileTitle.substring(pattern.exec(sFileTitle).index + 1, sFileTitle.length);  //index是点的位置。点的位置加1再到结尾
        return fileType01;
    }

    function fileinfo(fileid, callback) {
        var formData = new FormData();
        formData.append("action", "fileinfo");
        formData.append("file", fileid);
        $.ajax({
            type: 'POST',
            url: "_resource.html",
            data: formData,
            processData: false,
            contentType: false,
            dataType: "json",
            success: function (res) {
                if (!$.yqDataErrCheck(res)) {
                    return;
                }

                callback(res);
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                console.log(XMLHttpRequest.responseText);
                callback(XMLHttpRequest.responseText);
            }
        });
    }

    function yqRsRootPath(callback) {
        var formData = new FormData();
        formData.append("action", "rootpath");
        $.ajax({
            type: 'POST',
            url: "_resource.html",
            data: formData,
            processData: false,
            contentType: false,
            dataType: "json",
            success: function (res) {
                if (!$.yqDataErrCheck(res)) {
                    return;
                }

                callback(res);
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                console.log(XMLHttpRequest.responseText);
                callback({ error: 9, info: XMLHttpRequest.responseText });
            }
        });
    }

    function yqRsSubPath(paths, callback) {
        var formData = new FormData();
        formData.append("action", "subpath");
        formData.append("paths", JSON.stringify(paths));
        $.ajax({
            type: 'POST',
            url: "_resource.html",
            data: formData,
            processData: false,
            contentType: false,
            dataType: "json",
            success: function (res) {
                if (!$.yqDataErrCheck(res)) {
                    return;
                }

                callback(res);
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                console.log(XMLHttpRequest.responseText);
                callback({ error: 9, info: XMLHttpRequest.responseText });
            }
        });
    }

    function convTrees(row) {
        var nodes = [];
        for (var i = 0; i < row.paths.length; i++) {
            var id = row.name == "" ? row.paths[i] : row.name + "/" + row.paths[i];
            var node = {
                id: id,
                text: row.paths[i],
                iconCls: "icon2-rs-folder",
                attributes: {
                    type: "path",
                    _text: row.paths[i],
                    open: false
                },
                children: []
            };
            node.state = "closed";
            nodes.push(node);
        }

        for (var i = 0; i < row.files.length; i++) {
            var id = row.name == "" ? row.files[i].name : row.name + "/" + row.files[i].name;
            var node = {
                id: id,
                text: row.files[i].name,
                iconCls: "icon2-rs-file",
                attributes: {
                    type: "file",
                    _text: row.files[i].name,
                    name: row.files[i].name,
                    size: row.files[i].size,
                    mine: row.files[i].mine,
                }
            };
            node.state = "open";
            nodes.push(node);
        }

        return nodes;
    }

    //位置处理
    function popPosition(dg_opt, prevent_e) {
        mdiinfo = getWindParams();

        if (prevent_e.clientX != 0 || prevent_e.clientY != 0) {
            dg_opt.left = prevent_e.clientX + mdiinfo.clientX;
            dg_opt.top = prevent_e.clientY + mdiinfo.clientY;

            if (dg_opt.left < 5) {
                dg_opt.left = 5;
            }

            if (dg_opt.top < 5) {
                dg_opt.top = 5;
            }

            if ((dg_opt.left + dg_opt.width) > ($(window).width() - 10)) {
                dg_opt.left = $(window).width() - 10 - dg_opt.width;
                if (dg_opt.left < 0) {
                    delete dg_opt.left;
                }
            }

            if ((dg_opt.top + dg_opt.height) > ($(window).height() - 55)) {
                dg_opt.top = $(window).height() - 55 - dg_opt.height;
                if (dg_opt.top < 0) {
                    delete dg_opt.top;
                }
            }
        }

        return dg_opt;

        //mdi窗体参数
        function getWindParams() { // 不传name返回所有值，否则返回对应值
            var self_width = 0;
            var self_height = 0;
            var clientX = 0;
            var clientY = 0;
            var target;
            if (window.top != window.self) {
                var _frame = null;
                var url = window.location.search;
                if (url.indexOf('?') == 0) {
                    url = url.substring(1);
                    url = url.split('&');
                    // 获取全部参数及其值
                    for (var i = 0; i < url.length; i++) {
                        var info = url[i].split('=');
                        if (info[0] == "_frame") {
                            _frame = decodeURI(info[1]);
                            break;
                        }
                    }

                    if (_frame == "") {
                        _frame = null;
                    }
                }

                if (_frame != null) {
                    target = window.parent;
                    var $form = $(window.parent.document).find("[name='_" + _frame + "']");
                    if ($form.length > 0) {
                        var $body = $form.closest('div.panel-body');
                        self_width = $body.css("width");
                        self_height = $body.css("height");

                        var target = $form.closest('div.layout-panel');
                        clientX = parseInt(target.css("left").replace("px", ""));
                    }
                    else {
                        self_width = $(window).width();
                        self_height = $(window).height();
                    }

                    var $top = $(window.parent.document).find("[name='_top']");
                    clientY = $top.height()
                }
                else {
                    target = window;
                    self_width = $(window).width();
                    self_height = $(window).height();
                }
            }
            else {
                target = window;
            }

            if (typeof self_width === "string") {
                self_width = parseInt(self_width.replace("px", ""));
            }
            if (typeof self_height === "string") {
                self_height = parseInt(self_height.replace("px", ""));
            }

            //待处理。。。。
            if (clientY > 0) {
                clientY += 45;
            }

            return {
                "target": window.top,
                "clientX": clientX,     //frame子窗体mid窗体中的位置（左上角位置）
                "clientY": clientY,     //
                "self_width": self_width,   //frame窗体的宽度
                "self_height": self_height  //frame窗体的高度
            };;
        }
    }

    //消息提醒
    function yqMessager(title, msg, timeout) {
        if (timeout === undefined) {
            timeout = 3000;
        }
        if (window.self == window.top) {
            $.messager.show({
                title: title,
                msg: msg,
                timeout: timeout,
                showType: 'show'
            });
        }
        else {
            window.top.$.messager.show({
                title: title,
                msg: msg,
                timeout: timeout,
                showType: 'show'
            });
        }
    }
})(jQuery);